Unity渐进式光照贴图烘焙详解
随着各大计算平台的算力稳步增长,特别是GPU技术的不断进化,原先可望而不可及的技术比如实时光线追踪技术开始逐步走入玩家的视野。一些先锋厂商甚至已经超出Demo的范畴,开始正式推出支持实时光追的游戏。
不过目前的实时光追技术还只能在配备了最新Nvidia RTX 20系列显卡的PC机上才能实现(前一代Nvidia 10系列显卡,比如GeForce 1080,1070,甚至1060也可以用软件实现实时光追,但是总体效果不佳)。
大多数玩家所在的移动平台上,目前并没有实时光追技术被正式推出。虽然有厂商如Imagination Technologies推出了移动端实时光追的架构设计和演示Demo(可查看Imagination官网:https://www.imgtec.com/powervr-ray-tracing/),但是这些技术要在主流手机厂商如华为,苹果,三星,小米等那里得到实际应用,还有一段不短的路程要走。
因此我们今天来聊一下一项“老”技术:光照贴图烘焙。虽然实时光追非常诱人非常好,目前来说要想实现好的光照效果,我们还是要依赖光照贴图烘焙技术来实现。
本文将以问答的方式来讲解Unity 2019.4版本中的Progressive Lightmapper(Unity 2018等之前版本中的Enlighten已在2019.4中正式弃用)。之所以选择问答的形式原因如下:
什么是光照贴图(Lightmap)?
为什么要用光照贴图?
场景中的光照信息大致可以分成两类:直接光照和间接光照。
只有直接光照的情况
渐进式光照贴图烘焙
对场景中模型的要求是什么?
使用渐进式光照烘焙对模型有以下几个要求:
1. 模型上不能有重叠的UV。
2. UV之间要有足够的间距以避免“渗色”现象的发生。
3. 因为光照贴图只能烘焙静态物体,所以我们要把需要参与烘焙的物体标记为Static。
下面两张图是在Unity中使用UV Inspector的界面。在Scene窗口选中模型以后,UV Inspector界面就会显示当前模型包含的所有UV。左侧为第一套UV用于纹理贴图;右侧为第二套UV用于光照贴图烘焙:
2. UV之间要有足够的间距以避免“渗色”现象的发生。“渗色”的发生因为两块UV之间的间隔不足,导致一块UV上的颜色“渗透”到了相邻的UV上。
3. 因为光照贴图只能烘焙静态物体,所以我们要把需要参与烘焙的物体标记为Static,如下图所示:
如上图所示,我们习惯上直接在Game Object上勾选右上角的Static复选框,然后把层级中所有物体标记为Static。不过对于光照贴图烘焙有意义的两项是Contribute GI和Reflection Probe Static,因此你也可以只勾选这两项。
上图中的Contribute GI(贡献全局光照)选项和Mesh Renderer中的Contribute Global Illumination(贡献全局光照)是联动的。如果我们勾选右上角的Contribute GI,Mesh Renderer组件中的Contribute Global Illumination也会被勾选,Receive GlobalIllumination(接受全局光照)则会被设置为Lightmaps,意指当前Game Object会使用光照贴图获取间接光照。
我们也可以把Receive Global Illumination设置成Light Probes,这时间接光照信息就会来自相关的光照探针(Light Probes)。
渐进式光照贴图烘焙对硬件的要求是什么?支持Unity的哪些渲染管线?
硬件要求:
1. 至少需要一块支持OpenCL 1.2的显卡
2. 至少2GB的显存
3. CPU支持SSE4.1指令
支持的渲染管线:
1. 内置渲染管线(Built-in Render Pipeline):支持Baked Indirect,Subtractive和Shadowmask光照模式。
2. 通用渲染管线(Universal Render Pipeline,简称URP):支持Baked Indirect,Subtractive和Shadowmask光照模式。
3. 高清渲染管线(High Definition Render Pipeline,简称HDRP):支持Baked Indirect和Shadowmask光照模式。
因为用于烘焙测试的两个场景都是基于HDRP来制作的,所以接下去的讲解我们将会围绕HDRP的光照烘焙模块来进行。
渐进式光照贴图烘焙出来的是什么?
光照贴图烘焙出来的是光照贴图(Lightmaps),光照探针(Light Probes)和反射探针(Reflection Probes)。
按照不同的Lighting Mode(光照模式),光照贴图烘焙出来的结果是不同的。
HDRP下Lighting窗口的光照模式支持Baked Indirect和Shadowmask两种(内置渲染管线和通用渲染管线请参考文档)。
1. Baked Indirect模式:
如果场景中的灯光模式设置为Mixed,那么这些灯光会给场景提供直接光照,间接光照信息则被烘焙到光照贴图和光照探针中。此选项适合中高端的平台,比如PC,主机。
2. Shadowmask模式:
如果场景中的灯光模式设置为Mixed,灯光会给场景提供直接光照,间接光照烘焙到光照贴图和光照探针中。Shadowmask和光照探针遮挡信息会被烘焙到阴影信息中。你可以在Project Settings > Quality窗口设置Shadowmask的模式(Shadowmask或者Distance Shadowmask两种模式可选)。此选项在游戏运行时比Baked Indirect模式性能更好,因为光照贴图中已经预先烘焙了阴影信息。
3. Subtractive模式:(在内置和通用渲染管线中支持)
场景中的直接光照,间接光照和阴影信息都会烘焙到光照贴图中。适合对性能敏感的平台比如移动端平台。
如果场景中光源设置为Mixed模式,在三种光照模式下动态和静态物体的行为可参考以下列表:
注:上述总结自Unity文档:https://docs.unity.cn/2019.4/Documentation/Manual/lighting-mode.html
以上对比中的Shadow Distance在三种不同渲染管线中设置的方式是不一样的,以下为设置详解。
(1)内置渲染管线:
打开Edit > Project Settings > Quality> Shadows > Shadow Distance。
(2)URP通用渲染管线:
打开Edit > Project Settings > Graphics中选择UniversalRenderPipelineAsset进行设置。
(3)HDRP高清渲染管线:
通过在场景中使用的Volume进行设置。
界面操作(HDRP示例):打开Window > Rendering > Lighting Settings窗口,在Mixed Lighting区域勾选Baked Global Illumination复选框,然后在Lighting Mode中选择光照模式:
注:HDRP中不支持Subtractive光照模式
渐进式光照贴图烘焙的CPU版本和GPU版本有什么区别?
CPU和GPU两个版本所用的底层技术相同,唯一的区别是:CPU版本使用CPU和内存进行计算;GPU版本使用显卡和显存进行计算。
1. 如果使用CPU版本进行烘焙,影响烘焙效率的是CPU的速度和内存的大小。
2. 如果使用GPU版本进行烘焙,影响烘焙效率的则是显卡的速度和显存的大小。
界面操作(HDRP示例):打开Window > Rendering > Lighting Settings窗口,在Lightmapping Settings区域可以选择使用哪个版本的ProgressiveLightmapper:
Lighting界面上那一堆参数理解一下?
选择好Lighting Mode和Lightmapper,我们来看一下具体的烘焙参数。确保打开Window > Rendering > Lighting Settings窗口。
在HDRP中进行光照烘焙时可以为整个场景指定一个用于烘焙的天空盒作为环境光,如下图所示:
我们可以在这里使用当前HDRP场景中使用的天空盒设置,也可以使用不同的天空盒设置。当然,如果你使用相同的天空盒,那么烘焙所得的光照贴图将会拥有与当前场景一样的环境光。
内置和通用渲染管线的环境光设置参数:
1 Prioritize View:
启用此选项,如果Scene窗口打开,系统会逐步烘焙Scene窗口看到的画面,然后再继续烘焙Scene画面之外的场景区域。
如果你在Scene窗口移动场景中物体,改变物体和灯光属性或者改变Scene窗口画面等操作,烘焙会及时调整,快速逐步烘焙改变后的画面。
通过这个方式,我们可以快速预览Scene窗口当前画面的间接光照信息,及时做出相应修改,加快迭代速度,而不必像之前使用Enlighten时需要等待烘焙全部完成以后才能看到结果。
在使用此选项时记得打开Auto Generate(自动生成)复选框。
2 采样设置相关:
此区域的设置跟烘焙时所用的采样方式和采样数值相关。
Filtering区域的设置用于光照贴图的降噪操作。降噪操作本质上是一个针对已经烘焙好的光照贴图做后处理的过程。
如果启用Filtering功能,系统会在把光照贴图的Direct,Indirect和AmbientOcclusion这三部分信息结合之前,分别为这三个部分应用降噪算法。
我们可以选择Auto(自动)或者Advanced(高级)两种方式。
关闭降噪设置
关闭降噪设置烘焙结果
打开降噪设置
打开降噪设置烘焙结果
接下去我们用一组测试数据来说明上述三个参数的关系(使用的项目是上面的夜间场景):
从上述测试数值可以总结如下:
以下截图是配置-6的烘焙参数和结果:
从上图中可以看到,在提高了Lightmap Resolution,增加了Lightmap Padding数值和Lightmap Size数值以后,从原先的119个UV重叠的物体下降到了94个UV重叠的物体。
那么UV重叠到底是什么意思?是因为我们在制作模型解UV的时候没有做到UV之间保持足够距离吗?
5 Compress Lightmaps:
默认启用,对光照贴图进行压缩操作。虽然压缩过的光照贴图可以减少内存占用,但是也会导致光照贴图质量下降。
为了计算出一个物体是否被另一个物体挡住从而算出相应的环境光遮蔽效果,系统需要使用射线来做侦测之用。此参数用于控制射线的长度。
射线的长度越长,光照贴图中由环境光遮蔽产生的阴影区域越多,反之越少(只有相邻很近的物体之间才会有环境光遮蔽产生的阴影)。
如果设置为0,意味着此射线为无限长;默认数值为1。因为数值0代表射线长度无限长,所以画面中的环境光遮蔽明显暗很多。
左滑查看效果对比
下面三张图比较了不同Indirect Contribution数值对画面整体的环境光遮蔽造成的影响,可以看到IndirectContribution越大,环境光遮蔽越暗(红色线条标出的区域最明显)。
左滑查看效果对比
8 Indirect Intensity和Albedo Boost:
9 Lightmap Parameters:
用于控制各项烘焙相关的参数。你可以使用预设的参数也可以自行创建参数并保存下来以便复用。
除了在烘焙窗口可以全局指定这些预设的参数,你也可以为场景中参与烘焙的模型的Mesh Renderer组件单独指定预设的参数,示例如下图所示:
不同显卡对GPU版本的烘焙效率有什么影响?
感谢Nvidia中国和攀升为这次测试提供相关测试机器(IPASON D 系列设计师电脑,官网:http://ipason.com/)。
以下是不同配置下6组光照烘焙参数配置所用的烘焙时长。
左滑查看烘焙结果对比
左滑查看烘焙结果对比
总结:用于测试的三块显卡Nvidia GeForce 2060s,2070s和2080Ti的区别是它们的CUDA核心和显存大小。可以看到无论是什么样的参数配置:CUDA核心越多,显存越大,烘焙时间越短。所以我们可以说:不差钱的直接上2080Ti,毕竟烘焙这块可以给你节省很多迭代时间;入门级可以考虑2060s,因为性能也不差。
相同场景使用CPU烘焙需要多长时间?
使用斯蓬扎夜间场景,烘焙参数和烘焙时长如下。与GPU版本相比,CPU版本所需的烘焙时间明显偏长。
可能大家会问:既然GPU版本那么快,为什么还要CPU版本?
答案是:进行光照贴图烘焙时,GPU版本使用的是显存。就目前的显卡来说,显存总是有限的,我们也无法像添加内存那样可以自行添加(内存也相对便宜很多)。如果当前场景在烘焙时所需的显存空间超出了当前显卡具备的显存大小,那么GPU版本就会停止工作。这时我们就需要一个后退的方法,那就是CPU版本来救场了:在烘焙过程中,如果Unity发现显存耗尽,Unity会把GPU版本自动切换到CPU版本。
为什么GPU版本开始烘焙以后,
有时候会自动切换成CPU版本?
GPU版本自动切换到CPU版本的原因是当前系统的可用显存不足,GPU版本无法继续进行正常的烘焙操作。
从GPU版本到CPU版本的切换会发生在准备烘焙阶段。在Unity编辑器的Console窗口可能会出现两段黄色的警报信息(第一段必出),示例图如下:
(可能出现)这一段是说降噪处理失败。请尝试警用降噪处理或者降低光照贴图大小。
我们在使用GPU烘焙的时候,需要注意的是:等待Prepare Baking…这个阶段结束,开始Baking的时候看是否会切换到CPU版本,如下图所示:
如果看到Baking…[ETA: xx:xx:xx],观察到没有切换到CPU版本的话,你可以放心之后会继续用GPU版本进行烘焙了。否则如果这时候你离座去干个别的事情,可能回来一看烘焙时间翻了10倍:因为自动切换到CPU版本。
如何避免GPU烘焙自动切换成CPU烘焙?
因为场景中参与烘焙的资源量大小是不一样的,所以完全避免切换是不可能的。
通过前面不同型号的GPU烘焙测试,可以知道确保能够在场景中使用GPU烘焙的前提条件是当前系统可用显存的大小。因此能否使用GPU烘焙就看我们的系统能否省出足够的显存给渐进式光照烘焙这个模块用。以下是一些节省系统显存的方法:
结语
渐进式光照贴图烘焙系统为我们提供了快速迭代的工作流和整个烘焙时长的预估,完全改变了之前使用Enlighten系统时对所需烘焙时长完全靠猜,以及光照贴图烘焙效果要等到烘焙完成以后才能看到的问题。这大大加快了光照烘焙的速度,也让灯光美术师有了更多的自由度获得自己想要的效果。
不过要想用好这个系统,除了需要深入了解每个参数背后的意义,使用不同的场景(户外,室内,或者像斯蓬扎这种既有室内部分也有户外部分的场景)针对不同的参数做各种测试是非常关键的。通过这些测试练习,我们可以增加对这些参数以及这些参数之间如何配合的直观感受,有助于我们日常工作中在面对不同类型的场景时,能够在保证速度的情况下,烘焙出高质量的光照贴图。
每一个“在看”,都是我们前进的动力